package cc.eddic.pratice.programmingparadigms.emp01array.impl;

import cc.eddic.pratice.programmingparadigms.Employee;
import cc.eddic.pratice.programmingparadigms.Result;
import cc.eddic.pratice.programmingparadigms.ResultComparator;
import cc.eddic.pratice.programmingparadigms.emp01array.EmployeeStatisticsService;
import cc.eddic.pratice.programmingparadigms.emp02list.EmployeeList;
import cc.eddic.pratice.programmingparadigms.emp02list.ResultList;
import cc.eddic.pratice.programmingparadigms.emp02list.impl.ResultListGcsImpl;


import java.util.Objects;

public class StatisticsLhImpl extends ReaderGcsImpl implements EmployeeStatisticsService {

    @Override
    public Result[] pivotByGender(Employee[] employees) {
        String[] inf = new String[employees.length];
        for (int i = 0; i < inf.length; i++) {
            inf[i] = employees[i].getGender();
        }
        return getResults(inf);
    }

    @Override
    public Result[] pivotByDepartment(Employee[] employees) {
        String[] inf = new String[employees.length];
        for (int i = 0; i < inf.length; i++) {
            inf[i] = employees[i].getDepartment();
        }
        return getResults(inf);
    }


    public ResultList pivotByDepartment(EmployeeList employees) {
        ResultList resultList = new ResultListGcsImpl(employees.size());
        for (int i = 0; i < employees.size(); i++) {
            Employee emp = employees.get(i);
            Result r = resultList.findByKey(emp.getDepartment());
            if (null == r) {
                resultList.add(new Result(emp.getDepartment(), 1));
            } else {
                r.setCount(r.getCount() + 1);
            }
        }
        // Count 正排序
        resultList.sort(new ResultComparator() {
            @Override
            public int compare(Result r1, Result r2) {
                return r1.getCount() - r2.getCount();
            }
        });
        return resultList;
    }

    @Override
    public Result[] pivotByJobTitle(Employee[] employees) {
        String[] inf = new String[employees.length];
        for (int i = 0; i < inf.length; i++) {
            inf[i] = employees[i].getJobTitle();
        }
        return getResults(inf);
    }


    public ResultList pivotByJobTitle(EmployeeList employees) {
        ResultList resultList = new ResultListGcsImpl(employees.size());
        for (int i = 0; i < employees.size(); i++) {
            Employee emp = employees.get(i);
            Result r = resultList.findByKey(emp.getJobTitle());
            if (null == r) {
                resultList.add(new Result(emp.getJobTitle(), 1));
            } else {
                r.setCount(r.getCount() + 1);
            }
        }
        // Count 倒排序
        resultList.sort(new ResultComparator() {
            @Override
            public int compare(Result r1, Result r2) {
                return r2.getCount() - r1.getCount();
            }
        });
        return resultList;
    }

    public Result[] getResults(String[] inf) {
        Result[] results = new Result[inf.length];
        int index = 0;
        for (String s : inf) {
            boolean found = false;
            for (Result result : results) {
                if (null == result)
                    break;
                if (Objects.equals(result.getKey(), s)) {
                    found = true;
                    result.setCount(result.getCount() + 1);
                    break;
                }
            }
            if (!found) {
                results[index++] = new Result(s);
            }
        }
        return reverseResult(isNotNull(results, index), index);
    }

    public Result[] isNotNull(Result[] results, int index) {
        Result[] newresult = new Result[index];
        System.arraycopy(results, 0, newresult, 0, index);
        return newresult;
    }

    public Result[] reverseResult(Result[] results, int index) {
        if (index == 1) return results;
        Result max ;
        for (int i = 1; i < index; i++) {
            if (results[i - 1].getCount() < results[i].getCount()) {
                max = results[i - 1];
                results[i - 1] = results[i];
                results[i] = max;
            }
        }
        index--;
        reverseResult(results, index);
        return results;
    }
}
